package ndk.caro.algorithms;

import android.graphics.Point;
import ndk.caro.gameplays.myCaroGame;
import ndk.caro.gameplays.myPiece;

public class myAlgorithms {
	 // ************** VARIABLE ******************************
    public int iCurrPlayer = myPiece.NONE;
    public myCaroGame mCaroGame;
    public int iEnd = myPiece.NONE ; 
    public myEvalueBoard EBoard;
    
    // Sinh nuoc di - do thong minh cua may.
    public int Depth = 0;
    static public int MaxDepth = 21;
    static public int MaxBreadth = 8;
    
    public Point[] WinMoves = new Point[MaxDepth + 1];
    public Point[] MyMoves = new Point[MaxBreadth + 1];
    public Point[] HisMoves = new Point[MaxBreadth + 1];
    public boolean bWin, bLose;

    // Phong thu chat, tan cong nhanh.
    public int[] TScore;
    public int[] KScore;
 
    public myAlgorithms() { }
    // With Parent form.
    public myAlgorithms(myCaroGame mCaroGame)
    {
    	this.mCaroGame = mCaroGame;        
        EBoard = new myEvalueBoard(this);    
    }

    // Luong gia cho ban co - kinh nghiem cua may.
    public void EvalueGomokuBoard(int player)
    {
        int rw, cl, i;
        int cntHuman, cntMachine;

        // Luong gia cho hang.
        for (rw = 1; rw <= myCaroGame.iGAME_SIZE -2; rw++)
            for (cl = 1; cl <= myCaroGame.iGAME_SIZE - 6; cl++)
            {
                cntHuman = 0; cntMachine = 0;
                for (i = 0; i < 5; i++)
                {
                	
                    if (this.mCaroGame.getPiece(rw, cl + i).getValue() == myPiece.iOPLAYER) cntHuman++;
                    if (this.mCaroGame.getPiece(rw, cl + i).getValue() == myPiece.iXPLAYER) cntMachine++;
                }
                // Luong gia...
                if (cntHuman * cntMachine == 0 && cntHuman != cntMachine)
                    for (i = 0; i < 5; i++)
                        if (this.mCaroGame.getPiece(rw, cl + i).getValue() == myPiece.NONE)
                        {
                            if (cntMachine == 0)
                            {                 
                                if (player == myPiece.iXPLAYER)                             	
                                	this.EBoard.Board[rw][ cl + i] += TScore[cntHuman];                            
                                else EBoard.Board[rw][ cl + i] += KScore[cntHuman];                                
                            
                                // Truong hop bi chan 2 dau.
                            //    if(rw < myCaroGame.iGAME_SIZE && cl -1 < myCaroGame.iGAME_SIZE  && rw < myCaroGame.iGAME_SIZE && cl + 5 < myCaroGame.iGAME_SIZE) 
                                if (this.mCaroGame.getPiece(rw,cl - 1).getValue() == myPiece.iXPLAYER && this.mCaroGame.getPiece(rw,cl + 5).getValue() == myPiece.iXPLAYER)
									EBoard.Board[rw][ cl + i] = 0;
                            }
                            
                         
                            
                            if (cntHuman == 0) 
                            {
                                if (player == myPiece.iXPLAYER) EBoard.Board[rw][cl + i] += TScore[cntMachine];
                                else EBoard.Board[rw][cl + i] += KScore[cntMachine];
                                // Truong hop bi chan 2 dau.
                                //if(rw < myCaroGame.iGAME_SIZE && cl -1 < myCaroGame.iGAME_SIZE && rw < myCaroGame.iGAME_SIZE && cl + 5 < myCaroGame.iGAME_SIZE) 
                                if (this.mCaroGame.getPiece(rw,cl - 1).getValue() == myPiece.iOPLAYER && this.mCaroGame.getPiece(rw,cl + 5).getValue() == myPiece.iOPLAYER)
                                    EBoard.Board[rw][cl + i] = 0;
                            }
                            
              
                            if ((cntHuman == 4 || cntMachine == 4)
                                && (this.mCaroGame.getPiece(rw,cl + i - 1).getValue() == myPiece.NONE || this.mCaroGame.getPiece(rw,cl + i + 1).getValue() == myPiece.NONE))
                                EBoard.Board[rw][cl + i] *= 2;
                        }
            	
            }
        
        // Luong gia cho cot.
        for (cl = 1; cl <= myCaroGame.iGAME_SIZE - 2; cl++)
            for (rw = 1; rw <= myCaroGame.iGAME_SIZE - 6; rw++)
            {
                cntHuman = 0; cntMachine = 0;
                for (i = 0; i < 5; i++)
                {
                    if (this.mCaroGame.getPiece(rw+i,cl).getValue() == myPiece.iOPLAYER) cntHuman++;
                    if (this.mCaroGame.getPiece(rw+i,cl).getValue() == myPiece.iXPLAYER) cntMachine++;
                }
                // Luong gia...
                if (cntHuman * cntMachine == 0 && cntMachine != cntHuman)
                    for (i = 0; i < 5; i++)
                        if (this.mCaroGame.getPiece(rw+i,cl).getValue() == myPiece.NONE)
                        {
                            if (cntMachine == 0)
                            {
                                if (player == myPiece.iXPLAYER) EBoard.Board[rw + i][cl] += TScore[cntHuman];
                                else EBoard.Board[rw + i][cl] += KScore[cntHuman];
                                // Truong hop bi chan 2 dau.
                               // if(rw - 1 < myCaroGame.iGAME_SIZE && cl < myCaroGame.iGAME_SIZE  && rw + 5 <myCaroGame.iGAME_SIZE && cl < myCaroGame.iGAME_SIZE ) 
                                if (this.mCaroGame.getPiece(rw - 1,cl).getValue() == myPiece.iXPLAYER && this.mCaroGame.getPiece(rw + 5,cl).getValue() == myPiece.iXPLAYER)
                                    EBoard.Board[rw + i][cl] = 0;
                            }
                            if (cntHuman == 0)
                            {
                                if (player == myPiece.iOPLAYER) EBoard.Board[rw + i][cl] += TScore[cntMachine];
                                else EBoard.Board[rw + i][cl] += KScore[cntMachine];
                                // Truong hop bi chan 2 dau.
                                //if(rw -1 < myCaroGame.iGAME_SIZE && cl < myCaroGame.iGAME_SIZE && rw + 5 <myCaroGame.iGAME_SIZE && cl <myCaroGame.iGAME_SIZE ) 
                                if (this.mCaroGame.getPiece(rw-1,cl).getValue() == myPiece.iOPLAYER && this.mCaroGame.getPiece(rw+5,cl).getValue() == myPiece.iOPLAYER)
                                    EBoard.Board[rw+i][cl] = 0;
                            
                            }
                            if ((cntHuman == 4 || cntMachine == 4)
                                && (this.mCaroGame.getPiece(rw+i,cl).getValue() == myPiece.NONE || this.mCaroGame.getPiece(rw + i + 1,cl).getValue() == myPiece.NONE))
                                EBoard.Board[rw + i][cl] *= 2;
                        }
            }

        
        // Luong gia cho duong cheo xuong.
        for (rw = 1; rw <= myCaroGame.iGAME_SIZE - 6; rw++)
            for (cl = 1; cl <= myCaroGame.iGAME_SIZE - 6; cl++)
            {
                cntHuman = 0; cntMachine = 0;
                for (i = 0; i < 5; i++)
                {
                    if (this.mCaroGame.getPiece(rw+i,cl+i).getValue() == myPiece.iOPLAYER) cntHuman++;
                    if (this.mCaroGame.getPiece(rw+i,cl+i).getValue() == myPiece.iXPLAYER) cntMachine++;
                }
                // Luong gia...
                if (cntHuman * cntMachine == 0 && cntMachine != cntHuman)
                    for (i = 0; i < 5; i++)
                        if (this.mCaroGame.getPiece(rw+i,cl+i).getValue() == myPiece.NONE)
                        {
                            if (cntMachine == 0)
                            {
                                if (player == myPiece.iXPLAYER) EBoard.Board[rw+i][cl + i] += TScore[cntHuman];
                                else EBoard.Board[rw+i][cl + i] += KScore[cntHuman];
                                // Truong hop bi chan 2 dau.
                               // if(rw -1 < myCaroGame.iGAME_SIZE && cl -1 < myCaroGame.iGAME_SIZE && rw + 5 < myCaroGame.iGAME_SIZE && cl + 5 < myCaroGame.iGAME_SIZE) 
                                if (this.mCaroGame.getPiece(rw-1,cl-1).getValue() == myPiece.iXPLAYER && this.mCaroGame.getPiece(rw+5,cl+5).getValue() == myPiece.iXPLAYER)
                                    EBoard.Board[rw + i][cl + i] = 0;
                            }
                            if (cntHuman == 0)
                            {
                                if (player == myPiece.iOPLAYER) EBoard.Board[rw + i][cl + i] += TScore[cntMachine];
                                else EBoard.Board[rw + i][ cl + i] += KScore[cntMachine];
                                // Truong hop bi chan 2 dau.
                               // if(rw -1 < myCaroGame.iGAME_SIZE && cl -1 < myCaroGame.iGAME_SIZE && rw + 5 < myCaroGame.iGAME_SIZE && cl + 5 < myCaroGame.iGAME_SIZE ) 
                                if (this.mCaroGame.getPiece(rw-1,cl-1).getValue() == myPiece.iOPLAYER && this.mCaroGame.getPiece(rw+5,cl+5).getValue() == myPiece.iOPLAYER)
                                    EBoard.Board[rw + i][cl + i] = 0;
                            }
                            if ((cntHuman == 4 || cntMachine == 4)
                                && (this.mCaroGame.getPiece(rw + i - 1,cl + i - 1).getValue() == myPiece.NONE || this.mCaroGame.getPiece(rw + i + 1, cl + i + 1).getValue() == myPiece.NONE))
                                EBoard.Board[rw + i][cl + i] *= 2;
                        }
            }

        // Luong gia cho duong cheo len.
        for (rw = 5; rw <= myCaroGame.iGAME_SIZE - 6; rw++)
            for (cl = 1; cl <= myCaroGame.iGAME_SIZE - 6; cl++)
            {
                cntMachine = 0; cntHuman = 0;
                for (i = 0; i < 5; i++)
                {
                    if (this.mCaroGame.getPiece(rw - i,cl + i).getValue() == myPiece.iOPLAYER) cntHuman++;
                    if (this.mCaroGame.getPiece(rw - i,cl + i).getValue() == myPiece.iXPLAYER) cntMachine++;
                }
                // Luong gia...
                if (cntHuman * cntMachine == 0 && cntHuman != cntMachine)
                    for (i = 0; i < 5; i++)
                        if (this.mCaroGame.getPiece(rw-i,cl + i).getValue() == myPiece.NONE)
                        {
                            if (cntMachine == 0)
                            {
                                if (player == myPiece.iXPLAYER) EBoard.Board[rw - i][cl + i] += TScore[cntHuman];
                                else EBoard.Board[rw - i][cl + i] += KScore[cntHuman];
                                // Truong hop bi chan 2 dau.
                                //if(rw + 1 < myCaroGame.iGAME_SIZE && cl -1 < myCaroGame.iGAME_SIZE && rw - 5 < myCaroGame.iGAME_SIZE && cl + 5 < myCaroGame.iGAME_SIZE) 
                                if (this.mCaroGame.getPiece(rw + 1, cl - 1).getValue() == myPiece.iXPLAYER && this.mCaroGame.getPiece(rw - 5, cl + 5).getValue() == myPiece.iXPLAYER)
                                    EBoard.Board[rw - i][ cl + i] = 0;
                            }
                            if (cntHuman == 0)
                            {
                                if (player == myPiece.iOPLAYER) EBoard.Board[rw - i][cl + i] += TScore[cntMachine];
                                else EBoard.Board[rw - i][cl + i] += KScore[cntMachine];
                                // Truong hop bi chan 2 dau.
                                //if(rw + 1 < myCaroGame.iGAME_SIZE && cl -1 < myCaroGame.iGAME_SIZE && rw - 5 <myCaroGame.iGAME_SIZE && cl + 5 < myCaroGame.iGAME_SIZE)                            
                                if (this.mCaroGame.getPiece(rw + 1,cl - 1).getValue() == myPiece.iOPLAYER && this.mCaroGame.getPiece(rw - 5, cl + 5).getValue() == myPiece.iOPLAYER)
                                    EBoard.Board[rw - i][ cl + i] = 0;
                            }
                            if ((cntHuman == 4 || cntMachine == 4)
                                && (this.mCaroGame.getPiece(rw - i + 1,cl + i - 1).getValue() == myPiece.NONE || this.mCaroGame.getPiece(rw - i - 1,cl + i + 1).getValue() == myPiece.NONE))
                                EBoard.Board[rw - i][ cl + i] *= 2;
                        }
            }
    }   
        
    // Ham de quy - Sinh nuoc di cho may.
    public void GenerateMoves()
    {
        if (Depth >= MaxDepth) return;
        Depth++;
        boolean lose = false;
        bWin = false;

        Point MyNode = new Point();   // Duong di quan ta.
        Point HisNode = new Point();  // Duong di doi thu.
        int count = 0;

        // Luong gia cho ma tran.
        EvalueGomokuBoard(myPiece.iXPLAYER);
        
        // Lay MaxBreadth nuoc di tot nhat.
        for (int i = 1; i <= MaxBreadth; i++)
        {
            MyNode = EBoard.GetMaxNode();
            MyMoves[i] = MyNode;
            EBoard.Board[MyNode.x][MyNode.y] = 0;
        }
        // Lay nuoc di ra khoi danh sach - Danh thu nuoc di.
        count = 0;
        while (count < MaxBreadth)
        {
            count++;
            MyNode = MyMoves[count];
            WinMoves[Depth] = MyNode;
           // WinMoves.SetValue(MyNode, Depth);
            this.mCaroGame.setPiece(MyNode.x,MyNode.y, myPiece.iXPLAYER);

            // Tim cac nuoc di toi uu cua doi thu.
            EBoard.ResetBoard();
            EvalueGomokuBoard(myPiece.iOPLAYER);
            for (int i = 1; i <= MaxBreadth; i++)
            {
                HisNode = EBoard.GetMaxNode();
                HisMoves[i] = HisNode;
                EBoard.Board[HisNode.x][HisNode.y] = 0;
            }

            for (int i = 1; i <= MaxBreadth; i++)
            {
                HisNode = HisMoves[i];
                this.mCaroGame.setPiece(HisNode.x,HisNode.y,myPiece.iOPLAYER);
                // Kiem tra ket qua nuoc di.
                if (this.mCaroGame.CheckEnd(MyNode.x,MyNode.y) == myPiece.iXPLAYER)
                    bWin = true;
                if (this.mCaroGame.CheckEnd(HisNode.x,HisNode.y) == myPiece.iOPLAYER)
                    lose = true;

                if (lose)
                {
                    // Loai nuoc di thu.
                    bLose = true;
                    this.mCaroGame.setPiece(HisNode.x,HisNode.y,myPiece.NONE);
                    this.mCaroGame.setPiece(MyNode.x,MyNode.y,myPiece.NONE);
                    return;
                }

                if (bWin)
                {
                    // Loai nuoc di thu.
                    this.mCaroGame.setPiece(HisNode.x,HisNode.y,myPiece.NONE);
                    this.mCaroGame.setPiece(MyNode.x,MyNode.y,myPiece.NONE);
                    return;
                }
                else GenerateMoves(); // tim tiep.
                // Loai nuoc di thu.
                this.mCaroGame.setPiece(HisNode.x,HisNode.y,myPiece.NONE);
            }
            
            this.mCaroGame.setPiece(MyNode.x,MyNode.y,myPiece.NONE);
        }
        
    }
    // Goi Generator - Tim duong di cho may.
    public void GetGenResult()
    {
    	bWin = bLose = false;
        // Xoa mang duong di.
        WinMoves = new Point[MaxDepth + 1];
        for (int i = 0; i <= MaxDepth; i++)
            WinMoves[i] = new Point();
        
        // Xoa stack.
        for (int i = 0; i < MaxBreadth; i++)
            MyMoves[i] = new Point();

        Depth = 0;
        GenerateMoves();
    
    }
    
}
